React 中,PureComponent 和 React.memo 是兩個常用來優化性能的工具,它們的作用是幫助 React 自動對比 props 的變化,並只在 props 改變時才重新渲染子組件,從而避免不必要的渲染。
import React, { useState } from 'react';
// 普通的子組件
const ChildComponent = ({ count }) => {
console.log('ChildComponent 重新渲染');
return <div>計數: {count}</div>;
};
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState('');
return (
<div>
<h1>React 優化對照組</h1>
<ChildComponent count={count} />
<button onClick={() => setCount(count + 1)}>增加計數</button>
<input value={input} onChange={(e) => setInput(e.target.value)} />
</div>
);
}
export default App;
每次你更改輸入框的值,App 組件重新渲染,子組件 ChildComponent 也會重新渲染,即使它的 props 沒有改變。你會在控制台中看到 "ChildComponent 重新渲染" 每次輸入變更時出現,這就是性能浪費的情況。
import React, { useState, PureComponent } from 'react';
// 使用 PureComponent 優化子組件
class ChildComponent extends PureComponent {
render() {
console.log('ChildComponent 重新渲染');
return <div>計數: {this.props.count}</div>;
}
}
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState('');
return (
<div>
<h1>React 優化實驗組 - PureComponent</h1>
<ChildComponent count={count} />
<button onClick={() => setCount(count + 1)}>增加計數</button>
<input value={input} onChange={(e) => setInput(e.target.value)} />
</div>
);
}
export default App;
如果忘記props可以去看一下父子組件,所以可從觀察中發現發現PureComponent
專注於組件的渲染控制。
import React, { useState, memo } from 'react';
// 使用 React.memo 優化子組件
const ChildComponent = memo(({ count }) => {
console.log('ChildComponent 重新渲染');
return <div>計數: {count}</div>;
});
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState('');
return (
<div>
<h1>React 優化實驗組 - React.memo</h1>
<ChildComponent count={count} />
<button onClick={() => setCount(count + 1)}>增加計數</button>
<input value={input} onChange={(e) => setInput(e.target.value)} />
</div>
);
}
export default App;
跟上面那個挺像的,但是一個支援定義出來的函數一個不支援(範例const a=function ...),所以根據現代趨勢多已後者使用為多,至於他們的觀察對象都是組件的props。
特性 | PureComponent | React.memo |
---|---|---|
適用對象 | 類組件 | 函數組件 |
比較方式 | 自動淺比較,不支持自定義 | 默認淺比較,支持自定義比較函數 |
語法靈活性 | 只能用於類組件 | 只適用於函數組件 |
應用場景 | 傳統 React 應用,類組件 | 現代 React 應用,函數組件和 Hooks |
自定義比較邏輯 | 不支持 | 支持,自定義函數可以控制何時渲染 |
總結這兩篇的優化
特性 | PureComponent / React.memo | useMemo / useCallback |
---|---|---|
目的 | 優化子組件的渲染,避免不必要的重渲染 | 優化函數和計算的記憶,避免不必要的重新計算或函數創建 |
應用場景 | 防止子組件在 props 沒變時重新渲染 |
防止每次渲染時重新計算值或重新創建函數 |
使用對象 | 子組件的 props 比較(基於淺比較) |
計算值或函數的記憶 |
使用方式 | PureComponent 用於類組件,React.memo 用於函數組件 |
useMemo 記憶計算結果,useCallback 記憶函數 |
如何工作 | 自動對 props 進行淺比較,只有 props 發生變化時才重新渲染 |
通過依賴項控制函數或值的重新計算或創建,只有依賴變化時才更新 |
今天就這樣囉